package com.mune.gulimall.authserver.web;

import com.alibaba.fastjson.TypeReference;
import com.mune.common.constant.AuthServerConstant;
import com.mune.common.exception.BizCodeEnum;
import com.mune.common.to.MemberSessionTo;
import com.mune.common.utils.R;
import com.mune.gulimall.authserver.feign.MemberFeignService;
import com.mune.gulimall.authserver.feign.ThirdPartFeignService;
import com.mune.gulimall.authserver.vo.UserLoginVo;
import com.mune.gulimall.authserver.vo.UserRegisterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Controller
public class LoginController {
  @Autowired
  ThirdPartFeignService thirdPartFeignService;
  @Autowired
  RedisTemplate<String, Object> redisTemplate;
  @Autowired
  MemberFeignService memberFeignService;

  @ResponseBody
  @GetMapping("/sms/sendcode")
  public R sendCode(@RequestParam("phone") String phone) {
    Object redisResp = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
    String redisCode = redisResp == null ? "" : redisResp.toString();
    if (!StringUtils.isEmpty(redisCode)) {
      long l = Long.parseLong(redisCode.split("_")[1]);
      if (System.currentTimeMillis() - l < 60000) {
        return R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(), BizCodeEnum.SMS_CODE_EXCEPTION.getMessage());
      }
    }
    String code = UUID.randomUUID().toString().substring(0, 5);
    String substring = code + "_" + System.currentTimeMillis();
    thirdPartFeignService.sendCode(phone, code);
    redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone, substring, 10, TimeUnit.MINUTES);
    return R.ok();
  }

  @GetMapping("/login.html")
  public String loginPage(HttpSession session) {
    if (session.getAttribute(AuthServerConstant.LOGIN_USER) != null) return "redirect:http://gulimall.com";
    return "login";
  }

  @PostMapping("/register")
  public String register(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes) {
    if (result.hasErrors()) {
      Map<String, String> collect = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
      redirectAttributes.addFlashAttribute("errors", collect);
      return "redirect:http://auth.gulimall.com/register.html";
    }
    Object redisResp = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
    String redisCode = redisResp == null ? "" : redisResp.toString();
    if (!StringUtils.isEmpty(redisCode) && redisCode.split("_")[0].equals(vo.getCode())) {
      redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
      R register = memberFeignService.register(vo);
      if (register.getCode() == 0) {
        return "redirect:http://auth.gulimall.com/login.html";
      } else {
        Map<String, String> errors = new HashMap<>();
        errors.put("msg", register.getData("msg", new TypeReference<String>() {
        }));
        redirectAttributes.addFlashAttribute("errors", errors);
        return "redirect:http://auth.gulimall.com/register.html";
      }
    } else {
      Map<String, String> collect = new HashMap<>();
      collect.put("code", "验证码错误");
      redirectAttributes.addFlashAttribute("errors", collect);
      return "redirect:http://auth.gulimall.com/register.html";
    }
  }

  @PostMapping("/login")
  public String login(UserLoginVo vo, HttpSession session, RedirectAttributes redirectAttributes) {
    R login = memberFeignService.login(vo);
    if (login.getCode() == 0) {
      MemberSessionTo data = login.getData(new TypeReference<MemberSessionTo>() {
      });
      session.setAttribute(AuthServerConstant.LOGIN_USER, data);
      return "redirect:http://gulimall.com";
    }
    Map<String, String> errors = new HashMap<>();
    errors.put("msg", login.getData("msg", new TypeReference<String>() {
    }));
    redirectAttributes.addFlashAttribute("errors", errors);
    return "redirect:http://auth.gulimall.com/login.html";
  }
}
